<template>
  <section class="form-design">
    <a-card class="left">
      <template v-for="(block, index) of common.controls" :key="block.type">
        <a-row :gutter="[12, 12]" :wrap="true" :class="{ 'mt-20': index > 0 }">
          <a-col :span="24" class="control-title">
            {{ block.title }}
          </a-col>
          <a-col :span="24">
            <draggable
              v-model="block.list"
              :group="{
                name: 'controls',
                pull: 'clone',
                put: false,
              }"
              :sort="false"
              :clone="cloneControl"
              @end="controlDragEnd"
              item-key="type"
            >
              <template #item="{ element }">
                <div class="control-list">
                  <div class="control-item" @click="addControl(element)">
                    <span> {{ element.title }} </span>
                    <span>
                      <cu-icon
                        :type="element.icon"
                        style="color: #999; font-size: 18px"
                      />
                    </span>
                  </div>
                </div>
              </template>
            </draggable>
          </a-col>
        </a-row>
      </template>
    </a-card>
    <section class="middle" @click="formItemClick()">
      <section class="phone">
        <div class="inner">
          <div class="title">
            {{ basicInfo.name || "未命名审批" }}
          </div>
          <div class="content hide-scroller-bar">
            <div v-if="!formList.length" class="no-data">
              选择左侧控件，拖拽到此处
            </div>
            <draggable
              v-model="formList"
              :group="{ name: 'formItem', pull: true, put: true }"
              @end="formDragEnd"
              item-key="key"
              :disabled="formType == 'ask_leave' || formType == 'fill_card'"
              data-type="normal"
              style="min-height: 100%; padding-bottom: 100px"
              :move="onMoveDrag"
              v-bind="dragOptions"
            >
              <template #item="{ element: formItem, index: formIndex }">
                <div
                  class="form-item"
                  :class="{
                    'bg-white': formItem.type != 'tips',
                    'active-item': formItem.key == currentFormItem.key,
                  }"
                  :style="{
                    cursor: formItem.isLock ? 'not-allowed' : 'all-scroll',
                    backgroundColor: formItem.isLock ? '#ececec' : '#fff',
                  }"
                  @click.stop="formItemClick(formItem)"
                >
                  <!-- 明细 -->
                  <div v-if="formItem.type == 'detail'" class="form-detail">
                    <div>
                      {{ formItem.setting.name }}
                    </div>
                    <div class="detail-box">
                      <!-- <div v-if="!formItem.formList.length" class="no-data">
                        可添加多个控件（不包含容器类控件）
                      </div> -->
                      <a-tooltip>
                        <template #title>
                          <span v-if="!formItem.formList.length">
                            可添加多个控件（不包含容器类控件）
                          </span>
                        </template>
                        <draggable
                          v-model="formItem.formList"
                          :group="{
                            name: 'formItem',
                            pull: true,
                            put: true,
                          }"
                          :data-key="formItem.key"
                          item-key="key"
                          data-type="container"
                          style="min-height: 80px"
                          :move="onMoveDrag"
                          v-bind="dragOptions"
                        >
                          <template #item="{ element, index }">
                            <div
                              class="detail-item"
                              :class="{
                                'bg-white': element.type != 'tips',
                                'active-item':
                                  element.key == currentFormItem.key,
                              }"
                              :style="{
                                cursor: element.isLock
                                  ? 'not-allowed'
                                  : 'all-scroll',
                                backgroundColor: element.isLock
                                  ? '#ececec'
                                  : '#fff',
                              }"
                              @click.stop="formItemClick(element, formItem)"
                            >
                              <FormShow :current="element" />
                              <div
                                class="remove"
                                v-show="element.key == currentFormItem.key"
                                @click="removeFormItem(formIndex, index)"
                              >
                                <CloseOutlined />
                              </div>
                            </div>
                          </template>
                        </draggable>
                      </a-tooltip>
                    </div>
                    <div class="add-detail bg-white">
                      <PlusOutlined />
                      增加明细
                    </div>
                  </div>
                  <!-- 其他表单数据 -->
                  <FormShow v-else :current="formItem" />
                  <!-- 删除 -->
                  <div
                    class="remove"
                    v-show="formItem.key == currentFormItem.key"
                    @click="removeFormItem(formIndex)"
                  >
                    <CloseOutlined />
                  </div>
                </div>
              </template>
            </draggable>
          </div>
        </div>
      </section>
    </section>
    <a-card class="right" v-if="showSettingForm" :title="currentFormItem.title">
      <a-alert
        :message="currentFormItem.tips"
        v-if="currentFormItem.tips"
        style="margin-bottom: 20px"
      />
      <a-form layout="vertical">
        <!-- 控件名称 -->
        <template v-if="currentFormItem.type == 'daterange'">
          <a-form-item
            required
            v-for="(name, i) of currentFormItem.setting.name"
            :key="i"
            :label="'控件名称' + (i + 1)"
          >
            <a-input v-model:value="currentFormItem.setting.name[i]" />
          </a-form-item>
        </template>
        <a-form-item label="控件名称" required v-else>
          <a-input
            v-model:value="currentFormItem.setting.name"
            :disabled="['tips'].includes(currentFormItem.type)"
          />
        </a-form-item>
        <!-- 提示文字 -->
        <a-form-item
          label="提示文字"
          v-if="currentFormItem.setting.placeholder != undefined"
        >
          <div>
            <a-textarea
              v-if="currentFormItem.type == 'tips'"
              :rows="4"
              v-model:value="currentFormItem.setting.placeholder"
            />
            <a-input v-else v-model:value="currentFormItem.setting.placeholder" />
          </div>
        </a-form-item>
        <!-- 单位 数字独有 -->
        <a-form-item
          label="单位"
          v-if="currentFormItem.setting.unit != undefined"
        >
          <a-input v-model:value="currentFormItem.setting.unit" />
        </a-form-item>
        <!-- 是否允许修改时长 -->
        <a-form-item
          label="是否允许修改时长"
          v-if="currentFormItem.setting.durationChange != undefined"
          extra="人员发起申请时，可修改自动计算的时长"
        >
          <a-switch v-model:checked="currentFormItem.setting.durationChange" />
        </a-form-item>
        <!--  设置数值范围 数字独有 -->
        <a-form-item
          label="设置数值范围"
          v-if="currentFormItem.setting.range != undefined"
        >
          <a-row align="middle">
            <a-col :span="10">
              <a-input-number
                v-model:value="currentFormItem.setting.range.min"
                style="width: 100%"
              />
            </a-col>
            <a-col :span="4" class="text-center">至</a-col>
            <a-col :span="10">
              <a-input-number
                v-model:value="currentFormItem.setting.range.max"
                style="width: 100%"
              />
            </a-col>
          </a-row>
        </a-form-item>
        <!-- 选项 单选多选有 -->
        <a-form-item label="选项" v-if="currentFormItem.setting.options">
          <div>
            <template
              v-for="(option, index) of currentFormItem.setting.options"
              :key="index"
            >
              <div class="flex-between mb-10">
                <a-input
                  v-model:value="currentFormItem.setting.options[index]"
                  @change="optionsValueChange(index, option)"
                />
                <a-button type="text" @click="deleteSelectItem(index)">
                  <CloseOutlined />
                </a-button>
              </div>
            </template>
            <a-button type="link" @click="addFormItemOptions">
              <template #icon>
                <PlusOutlined />
              </template>
              添加选项
            </a-button>
          </div>
        </a-form-item>
        <!-- 日期类型 选择日期、日期范围独有 -->
        <a-form-item
          label="日期类型"
          v-if="currentFormItem.setting.dateType"
          required
        >
          <a-radio-group v-model:value="currentFormItem.setting.dateType">
            <a-radio value="date"> 年-月-日 </a-radio>
            <a-radio value="datetime"> 年-月-日 时:分 </a-radio>
          </a-radio-group>
        </a-form-item>
        <!-- 默认值 -->
        <a-form-item
          label="默认值设置"
          v-if="currentFormItem.setting.setDefault != undefined"
          extra="请先填写所有下拉选项值，且勿填写重复项"
        >
          <div>
            <a-switch v-model:checked="currentFormItem.setting.setDefault" />
            <div class="mt-10" v-if="currentFormItem.setting.setDefault">
              <!-- 选项的默认值为下拉 -->
              <a-select
                v-if="currentFormItem.setting.options"
                :options="
                currentFormItem.setting.options.map((item) => ({
                  value: item,
                  label: item,
                }))
              "
                v-model:value="currentFormItem.setting.defaultValue"
                :disabled="
                currentFormItem.setting.options.findIndex((item) => !item) != -1
              "
              />
              <!-- 其他默认值为输入框 -->
              <a-input
                v-else
                v-model:value="currentFormItem.setting.defaultValue"
                placeholder="请输入"
              />
            </div>
          </div>
        </a-form-item>
        <!-- 必填 -->
        <a-form-item
          label="是否必填"
          v-if="currentFormItem.setting.required != undefined"
        >
          <a-switch v-model:checked="currentFormItem.setting.required" />
        </a-form-item>
        <!-- 选择房间组件的可选范围 -->
        <a-form-item
          label="房源信息"
          v-if="currentFormItem.setting.showRoomAll != undefined"
          extra="房源信息选择租客绑定房源，且游客和租客都可以发起时，若用户未绑定房源，在提交审批时会提示前往绑定房源"
        >
          <a-select v-model:value="currentFormItem.setting.showRoomAll">
            <a-select-option :value="true">全部房源</a-select-option>
            <a-select-option :value="false">租客绑定房源</a-select-option>
          </a-select>
        </a-form-item>
      </a-form>
    </a-card>
  </section>
</template>

<script>
import {
  computed,
  defineComponent,
  nextTick,
  reactive,
  toRaw,
  toRefs,
  watch,
} from "vue";
import store from "../../../../store";
import {
  CloseOutlined,
  RightOutlined,
  PlusOutlined,
} from "@ant-design/icons-vue";
import common from "../js/common";
import draggable from "vuedraggable";
import { message } from "ant-design-vue";
import { useRoute } from "vue-router";
import FormShow from "./FormShow.vue";

export default defineComponent({
  name: "FormDesign",
  components: {
    CloseOutlined,
    // RightOutlined,
    PlusOutlined,
    draggable,
    FormShow,
  },
  props: {
    trigger: {
      type: Number,
      default: 0,
    },
    formType: {
      type: String,
      default: "",
    },
  },
  setup(props, { emit }) {
    const basicInfo = computed(() => store.getters.approvalBasicInfo);
    let count = 0;

    const route = useRoute();

    const state = reactive({
      id: route.query.id,
      // 表单列表
      formList: [],
      //   当前选中的表单项
      currentFormItem: {},
      setDefaultDisabled: true,
    });

    const showSettingForm = computed(
      () =>
        state.currentFormItem &&
        state.currentFormItem.setting &&
        Object.keys(state.currentFormItem.setting).length
    );

    // 点击控件
    const formItemClick = (formItem, parentFormItem) => {
      if (
        !formItem ||
        formItem.key == state.currentFormItem.key ||
        formItem.isLock
      ) {
        state.currentFormItem = {};
      } else {
        if (parentFormItem) {
          formItem.parent_key = parentFormItem.key;
        }
        state.currentFormItem = formItem;
      }
    };

    // 添加控件
    const cloneControl = (control) => {
      count++;
      return {
        type: control.type,
        key: `${control.type}_${count}`,
        title: control.title,
        // order: count,
        tips: control.tips,
        formList: control.formList ? [] : undefined,
        setting: JSON.parse(JSON.stringify(control.setting)),
      };
    };
    const controlDragEnd = (e) => {
      console.log("-----------------controlDragEnd11", e);
      console.log("-----------------controlDragEnd", toRaw(state.formList));
      if (e.pullMode == "clone") {
        const detailKey = e.to.dataset.key;
        let index = e.newIndex;
        if (detailKey) {
          index = state.formList.findIndex((item) => item.key == detailKey);
          if (
            e.item.__draggable_context.element.type == "detail" &&
            e.to.dataset.type == "container"
          ) {
            state.formList[index].formList.splice(e.newIndex, 1);
            message.error("暂不支持该控件添加到明细");
            state.currentFormItem = state.formList[index];
          } else {
            state.currentFormItem = state.formList[index].formList[e.newIndex];
          }
        } else {
          state.currentFormItem = state.formList[index];
        }
      }
    };
    const addControl = (control) => {
      let currentIndex = -1;
      if (state.currentFormItem && Object.keys(state.currentFormItem).length) {
        currentIndex = state.formList.findIndex(
          (item) => item.key == state.currentFormItem.key
        );
      }
      state.currentFormItem = cloneControl(control);
      if (currentIndex == -1) {
        state.formList.push(state.currentFormItem);
      } else {
        state.formList.splice(currentIndex + 1, 0, state.currentFormItem);
      }
    };

    // 拖动表单控件
    const formDragEnd = (e) => {
      console.log("------------------formDragEnd", toRaw(state.formList));
    };

    const onMoveDrag = (e) => {
      // isLock的表单项禁止拖拽
      if (e.relatedContext.element && e.relatedContext.element.isLock) {
        return false;
      }
      return true;
    };

    const dragOptions = computed(() => {
      return {
        animation: 200,
        disabled: false,
        ghostClass: "ghost",
      };
    });

    // 移除控件
    const removeFormItem = (index, subIndex = -1) => {
      if (subIndex > -1) {
        state.formList[index].formList.splice(subIndex, 1);
      } else {
        state.formList.splice(index, 1);
      }
      Object.assign(state.currentFormItem, {});
    };

    // 添加选项
    const addFormItemOptions = () => {
      state.currentFormItem.setting.options.push("");
      optionsValueChange();
    };

    const optionsValueChange = (index, value) => {
      state.currentFormItem.setting.defaultValue = undefined;
    };

    const validateForm = () => {
      store.dispatch("SetFormDesign", state.formList).then(() => {
        emit("triggerChange", state.formList);
      });
    };

    const deleteSelectItem = (index) => {
      state.currentFormItem.setting.options.splice(index, 1);
      optionsValueChange();
    };

    const approvalDetail = computed(() => store.getters.approvalDetail);

    const init = () => {
      if (state.id) {
        watch(
          () => approvalDetail.value,
          (detail) => {
            if (detail && detail.id) {
              state.formList = detail.form;
              // 考虑到默认模板的key可能无序，不能直接取最后一个的key作为初始count
              let largestKey = 0;
              state.formList.forEach((formItem) => {
                if (formItem.type == "detail") {
                  formItem.formList.forEach((item) => {
                    const keyArr = item.key.split("_");
                    if (Number(keyArr[1]) > largestKey) {
                      largestKey = Number(keyArr[1]);
                    }
                  });
                } else {
                  const keyArr = formItem.key.split("_");
                  if (Number(keyArr[1]) > largestKey) {
                    largestKey = Number(keyArr[1]);
                  }
                }
              });
              count = largestKey;
            }
          }
        );
      }
    };

    init();

    watch(
      () => props.trigger,
      () => validateForm()
    );
    return {
      common,
      basicInfo,
      showSettingForm,
      approvalDetail,
      ...toRefs(state),
      controlDragEnd,
      cloneControl,
      addControl,
      formDragEnd,
      removeFormItem,
      formItemClick,
      addFormItemOptions,
      optionsValueChange,
      deleteSelectItem,
      onMoveDrag,
      dragOptions,
    };
  },
});
</script>

<style lang="less" scoped>
.form-design {
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: relative;

  .middle {
    width: 100%;
    height: 100%;
    overflow: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    .phone {
      width: 18%;
      min-width: 300px;
      max-width: 345px;
      height: 90%;
      border-radius: 20px;
      box-shadow: @box-shadow-base;
      background: #fff;
      padding: 15px;
      .inner {
        background: #f7f7f7;
        border: 1px solid #ddd;
        height: 100%;
        border-radius: 12px;
        overflow: hidden;
        display: flex;
        flex-direction: column;
        .title {
          height: 48px;
          line-height: 48px;
          text-align: center;
          background: #fff;
          border-bottom: 1px solid #ddd;
        }
        .content {
          flex: 1;
          overflow: hidden auto;
          // padding-bottom: 20px;
          position: relative;
          .no-data {
            position: absolute;
            left: 0;
            right: 0;
            top: 0;
          }

          .form-item {
            margin-top: 10px;
            line-height: 32px;
            padding: 8px 10px;
            position: relative;
            overflow: hidden;
            border: 1px solid transparent;
            // cursor: all-scroll;

            .placeholder {
              color: #999;
            }
            .upload {
              width: 48px;
              height: 48px;
              background: #f4f4f4;
              color: #999;
              display: flex;
              align-items: center;
              justify-content: center;
              font-size: 24px;
              margin: 4px 0;
            }
            .item-required {
              &::before {
                content: "*";
                color: @error-color;
                margin-right: 2px;
              }
            }
            .combine-item {
              padding: 8px 0px;
            }
            .form-detail {
              // background: #f7f7f7;
              // margin: -8px -10px;
              .detail-box {
                background: #f7f7f7;
                min-height: 100px;
                margin: 0px -10px;
                padding: 5px 0;
                .detail-item {
                  // background: #fff;
                  padding: 8px 10px;
                  position: relative;
                  overflow: hidden;
                  &:not(:first-child) {
                    margin-top: 5px;
                  }
                }
              }
              .add-detail {
                text-align: center;
                color: @primary-color;
                opacity: 0.6;
                margin-top: 4px;
              }
            }
          }
          .active-item {
            border: 1px solid @primary-color;
            // box-shadow: 1px 0px 1px 1px @primary-color;
            .remove {
              position: absolute;
              width: 48px;
              height: 48px;
              background: @primary-color;
              right: 0;
              top: 0;
              border-radius: 50%;
              transform: translate(50%, -50%);
              display: flex;
              align-items: flex-end;
              justify-content: flex-start;
              color: #fff;
              padding: 8px;
              font-size: 14px;
              cursor: pointer;
            }
          }
        }
      }
    }
  }
  .left,
  .right {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 360px;
    background: #fff;
    box-shadow: @box-shadow-base;
    overflow: auto;
  }
  .left {
    left: 0;
    .control-title {
      color: rgba(0, 0, 0, 1);
      font-size: 15px;
    }
    .control-list {
      display: inline-block;
      width: calc(50% - 10px);
      margin-bottom: 10px;
      margin-right: 10px;
      user-select: none;
      .control-item {
        display: flex;
        align-items: center;
        justify-content: space-between;
        border: 1px solid #ddd;
        height: 40px;
        padding: 0 10px;
        border-radius: 6px;
        cursor: all-scroll;
        color: rgba(0, 0, 0, 0.7);
      }
    }
  }
  .right {
    right: 0;
  }
}
</style>
